//
//  ST_BaseNetManager.m
//  ST_BaseMall
//
//  Created by 昱胜 on 2022/9/2.
//

#import "ST_BaseNetManager.h"
#import <PPNetworkHelper.h>
#import <MBProgressHUD.h>
#import "NSString+EquipmentInfo.h"

#import "HNSH_UploadLocalAlert.h"
#import "HNSH_NetConst.h"

@implementation ST_BaseNetManager

+ (ST_BaseNetManager *)shareManage {
    static ST_BaseNetManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[ST_BaseNetManager alloc]init];
    });
    return manager;
}

+ (__kindof NSURLSessionTask *)requestMethod:(HttpMethod)method
                                   urlString:(NSString *)urlString
                                      params:(NSDictionary * _Nullable )params
                                        from:(BOOL)from
                                     success:(ST_DataRequestSuccess)success
                                     failure:(ST_RequestFailure)failure {
    return [ST_BaseNetManager requestMethod:method urlString:urlString params:params from:from cache:NO showLoad:YES cacheData:success success:success failure:failure];
}

+ (__kindof NSURLSessionTask *)requestMethod:(HttpMethod)method
                                   urlString:(NSString *)urlString
                                      params:(NSDictionary * _Nullable )params
                                        from:(BOOL)from
                                       cache:(BOOL)cache
                                    showLoad:(BOOL)showLoad
                                   cacheData:(ST_DataRequestSuccess)cacheData
                                     success:(ST_DataRequestSuccess)success
                                     failure:(ST_RequestFailure)failure {
    __block NSURLSessionTask *task = nil;
    
    //添加请求头
    //token
    NSLog(@"token ==> %@ \n urlString ==> %@ \n params ==> %@",[ST_UserManager shareInstance].access_token,urlString,params);
    if (![NSString isBlankString:[ST_UserManager shareInstance].access_token]) {
        [PPNetworkHelper setValue:[NSString stringWithFormat:@"bearer %@",[ST_UserManager shareInstance].access_token] forHTTPHeaderField:@"Authorization"];
    } else {
        [PPNetworkHelper setValue:@"" forHTTPHeaderField:@"Authorization"];
    }
    //client
    NSString * client_info = [self getClientInfo];
    [PPNetworkHelper setValue:client_info forHTTPHeaderField:@"client-info"];
    
    if (from) {
        [PPNetworkHelper setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    } else {
        [PPNetworkHelper setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    }
    
    if (showLoad) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [MBProgressHUD showHUDAddedTo:kSTWindow animated:YES];
        });
    }
    urlString = [NSString stringWithFormat:@"%@%@",k_url_head,urlString];
    [PPNetworkHelper setValue:@"iOS" forHTTPHeaderField:@"channel"];
    [PPNetworkHelper setRequestTimeoutInterval:10];
    [PPNetworkHelper openNetworkActivityIndicator:YES];
    if (method == HttpMethodGet) {
        if (cache) {
            task = [PPNetworkHelper GET:urlString parameters:params responseCache:^(id responseCache) {
                ST_BaseNetModel *model = [ST_BaseNetModel successModel:responseCache urlString:urlString params:params];
                if (model.code == 200) {
                    !cacheData ?: cacheData(model);
                }
            } success:^(id responseObject) {
                [ST_BaseNetManager successMethod:method urlString:urlString params:params from:from cache:cache responseObject:responseObject cacheData:cacheData success:success failure:failure];
            } failure:^(NSError *error) {
                [ST_BaseNetManager failureWithError:error failure:failure];
            }];
        } else {
            task = [PPNetworkHelper GET:urlString parameters:params success:^(id responseObject) {
                [ST_BaseNetManager successMethod:method urlString:urlString params:params from:from cache:cache responseObject:responseObject cacheData:cacheData success:success failure:failure];
            } failure:^(NSError *error) {
                [ST_BaseNetManager failureWithError:error failure:failure];
            }];
        }
    } else if (method == HttpMethodPost) {
        if (cache) {
            task = [PPNetworkHelper POST:urlString parameters:params responseCache:^(id responseCache) {
                ST_BaseNetModel *model = [ST_BaseNetModel successModel:responseCache urlString:urlString params:params];
                !cacheData ?: cacheData(model);
            } success:^(id responseObject) {
                [ST_BaseNetManager successMethod:method urlString:urlString params:params from:from cache:cache responseObject:responseObject cacheData:cacheData success:success failure:failure];
            } failure:^(NSError *error) {
                [ST_BaseNetManager failureWithError:error failure:failure];
            }];
        } else {
            task = [PPNetworkHelper POST:urlString parameters:params success:^(id responseObject) {
                [ST_BaseNetManager successMethod:method urlString:urlString params:params from:from cache:cache responseObject:responseObject cacheData:cacheData success:success failure:failure];
            } failure:^(NSError *error) {
                [ST_BaseNetManager failureWithError:error failure:failure];
            }];
        }
    } else if (method == HttpMethodPut) {
        if (cache) {
            task = [PPNetworkHelper PUT:urlString parameters:params responseCache:^(id responseCache) {
                ST_BaseNetModel *model = [ST_BaseNetModel successModel:responseCache urlString:urlString params:params];
                !cacheData ?: cacheData(model);
            } success:^(id responseObject) {
                [ST_BaseNetManager successMethod:method urlString:urlString params:params from:from cache:cache responseObject:responseObject cacheData:cacheData success:success failure:failure];
            } failure:^(NSError *error) {
                [ST_BaseNetManager failureWithError:error failure:failure];
            }];
        } else {
            task = [PPNetworkHelper PUT:urlString parameters:params success:^(id responseObject) {
                [ST_BaseNetManager successMethod:method urlString:urlString params:params from:from cache:cache responseObject:responseObject cacheData:cacheData success:success failure:failure];
            } failure:^(NSError *error) {
                [ST_BaseNetManager failureWithError:error failure:failure];
            }];
        }
    } else if (method == HttpMethodDelete) {
        
    }
    return task;
}

static NSInteger refreshCont = 0;
+ (void)successMethod:(HttpMethod)method
            urlString:(NSString *)urlString
               params:(NSDictionary * _Nullable )params
                 from:(BOOL)from
                cache:(BOOL)cache
       responseObject:(id)responseObject
            cacheData:(ST_DataRequestSuccess)cacheData
              success:(ST_DataRequestSuccess)success
              failure:(ST_RequestFailure)failure {
    ST_BaseNetModel *model = [ST_BaseNetModel successModel:responseObject urlString:urlString params:params];
    dispatch_async(dispatch_get_main_queue(), ^{
        [MBProgressHUD hideHUDForView:kSTWindow animated:YES];
    });
    if (model.code == 0) {
        if (![urlString containsString:URL_Oauth_Refresh_Token]) {//排除刷新token请求
            refreshCont = 0;
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            !success ?: success(model);
        });
    } else if (model.code == 708 || model.code == 1001) {//重复请求
        
    } else if (model.code == 960) {//您的账号下有粉丝存在，不可注销
        dispatch_async(dispatch_get_main_queue(), ^{
            !success ?: success(model);
        });
    } else if (model.code == 961) {//您的账号中还有绿色能量、现金余额等资产，是否要进行注销？（有资金弹窗）
        dispatch_async(dispatch_get_main_queue(), ^{
            !success ?: success(model);
        });
    } else if (model.code == 962) {//账户一经注销，不可找回，不可重新注册，是否要进行注销？（无资金弹窗）
        dispatch_async(dispatch_get_main_queue(), ^{
            !success ?: success(model);
        });
    } else if (model.code == 730) {//归属地
        dispatch_async(dispatch_get_main_queue(), ^{
            HNSH_UploadLocalAlert *alert = [[HNSH_UploadLocalAlert alloc]initWithFrame:CGRectMake(0, 0, 300, 204)];
            [alert showView];
        });
    } else if (model.code == 401) {
        refreshCont ++;
        if (refreshCont >= 5) {
            [PPNetworkHelper cancelAllRequest];
            dispatch_async(dispatch_get_main_queue(), ^{
                [ST_UserManager logOut];
            });
            return;
        }
        [ST_BaseNetManager loadRefreshTokenComplate:^(BOOL isRefresh) {
            if (isRefresh) {
                [ST_BaseNetManager requestMethod:method urlString:urlString params:params from:from success:success failure:failure];
            }
        }];
    } else {
        dispatch_async(dispatch_get_main_queue(), ^{
            !success ?: success(model);
            [kSTWindow makeToast:model.msg];
        });
    }
}

+ (void)failureWithError:(NSError *)error failure:(ST_RequestFailure)failure{
    NSString *errorString = [NSString stringWithFormat:@"%@",error.userInfo[@"NSLocalizedDescription"]];
    if ([errorString containsString:@"401"]) {
        refreshCont ++;
        if (refreshCont >= 5) {
            [PPNetworkHelper cancelAllRequest];
            dispatch_async(dispatch_get_main_queue(), ^{
                [ST_UserManager logOut];
            });
            return;
        }
        [ST_BaseNetManager loadRefreshTokenComplate:^(BOOL isRefresh) {
            if (isRefresh) {
            }
        }];
    }
    dispatch_async(dispatch_get_main_queue(), ^{
        !failure ?: failure(error);
        [MBProgressHUD hideHUDForView:kSTWindow animated:YES];
    });
}

//刷新token
+ (void)loadRefreshTokenComplate:(void(^)(BOOL isRefresh))complate {
    if (![[ST_UserManager shareInstance].refresh_token isNotBlank]) {
        NSLog(@"没有refresh_token");
        return;
    }
    [HNSH_UserNetServer requestRefreshTokenSuccess:^(ST_BaseNetModel * _Nullable responseObject) {
        if (responseObject.code == 200) {
            [[ST_UserManager shareInstance] saveAccountInfoWithAccessToken:responseObject.resultset[@"access_token"] RefreshToken:responseObject.resultset[@"refresh_token"]];
            
            //请求三方信息
            [[ST_UserManager shareInstance] loadOtherTokenComplate:^{
                            
            }];
            if (complate) {
                complate(YES);
            }
        } else {
            [ST_UserManager logOut];
        }
    } Failure:^(NSError * _Nullable error) {

    }];
}



#pragma mark 七牛云上传
+ (void)uploadImageWithImageData:(UIImage *)image progress:(QNUpProgressHandler)progress complate:(ST_QiniuRequestSuccess)complate  {
    //获取token
    [HNSH_UserNetServer requestOssTokenSuccess:^(ST_BaseNetModel * _Nullable responseObject) {
        if (responseObject.code == 0) {
            
            //上传
            NSData *data = UIImageJPEGRepresentation(image, 0.5);
            if (!data) {
                return;
            }
            NSString * fileName = [NSString stringWithFormat:@"%@/%@.png",[[NSDate date] stringWithFormat:@"yyyy-MM-dd"], [NSString getNowTimeTimestamp]];
            NSString *token = [NSString stringWithFormat:@"%@",responseObject.resultset[@"token"]];
            NSString *domain = [NSString stringWithFormat:@"%@",responseObject.resultset[@"domain"]];
            QNUploadOption *opt = [[QNUploadOption alloc] initWithMime:nil
                                                       progressHandler:progress
                                                                params:nil
                                                              checkCrc:NO
                                                    cancellationSignal:nil];
            QNUploadManager *uploadManager = [QNUploadManager sharedInstanceWithConfiguration:nil];
            [uploadManager putData:data
                               key:fileName
                             token:token
                          complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
                if (info.statusCode == 200 && resp) {
                    NSString * urk_image = [NSString stringWithFormat:@"%@/%@",domain,key];
                    if (complate) {
                        complate(urk_image);
                    }
                } else {
                    [kSTWindow makeToast:info.message];
                }
            } option:opt];
        }
    } Failure:^(NSError * _Nullable error) {
        
    }];
}

//上传多张图片
+ (void)uploadImages:(NSArray *)imageArray progress:(void (^)(CGFloat percent))progress complate:(ST_QiniuRequestSuccess)complate {
    NSMutableArray *array = [[NSMutableArray alloc] init];
    __block CGFloat totalProgress = 0.0f;
    __block CGFloat partProgress = 1.0f / [imageArray count];
    __block NSUInteger currentIndex = 0;
    ST_BaseNetManager *uploadHelper = [ST_BaseNetManager shareManage];
    __weak typeof(uploadHelper) weakHelper = uploadHelper;
    uploadHelper.qnSuccess  = ^(NSString *url) {
        [array addObject:url];
        totalProgress += partProgress;
        progress(totalProgress);
        currentIndex++;
        if ([array count] == [imageArray count]) {
            complate([array copy]);
            return;
        }
        else {
            if (currentIndex < imageArray.count) {
                [ST_BaseNetManager uploadImageWithImageData:imageArray[currentIndex] progress:nil complate:weakHelper.qnSuccess];
            }
        }
    };
    [ST_BaseNetManager uploadImageWithImageData:imageArray[0] progress:nil complate:weakHelper.qnSuccess];
}


+ (NSString *)getClientInfo{
    NSDictionary * dic = @{
        @"platform":@"ios",
        @"phone_product":@"apple",
        @"phone_model":[NSString getEquipment_model],
        @"system_version":[NSString getEquipment_systemVersion],
        @"screen_size":[NSString getEquipment_scale],
        @"device_no":[NSString getEquipment_udid],
        @"version":[NSString getEquipment_version],
    };
    NSString * client_info = [dic jsonStringEncoded];
    return client_info;
}

@end
